package cloud.xiangyixiang.www.spring.boot.java.basics.controller;

/**
 * <p>
 * Java Exception 异常处理
 * </p>
 *
 * @author zhixinglu
 * @date 2023/9/2 15:17
 */
public class ExceptionController {


    public static void main(String[] args) {

        description();

        test01();

    }

    public static void description(){
        System.out.println("Q1: Exception和Error区别？");
        System.out.println("A1: Exception和Error都继承于Throwable 类，在 Java 中只有 Throwable 类型的实例才可以被抛出或捕获，它是异常处理机制的基本组成类型。\n" +
                "    Exception是可预料的异常情况，可以获取到这种异常，并对其进行业务外的处理。\n" +
                "    Error是不可预料的异常，error发生后，会直接导致JVM不可处理。\n" +
                "    Exception分为检查性异常、非检查性异常。\n" +
                "    检查性异常，必须在编写代码时，使用try catch捕获（比如：IOException异常）。\n" +
                "    非检查性异常，编译器不会发现这个地方是否会产生一次，比如空指针异常，这种异常是在代码编写或者使用过程中通过规范可以避免发生的。比如sts的findbugs功能就可以检测到代码的空指针异常。");

        System.out.println("Q2: try-catch内代码为什么越少越好吗？");
        System.out.println("A2: 民间有这样一个说法，trycatch的范围越小越好，这个谁都知道，为什么呢？因为效率低。为什么效率低呢？不知道了。\n" +
                "    try-catch与没有try-catch的代码，区别在于，前者阻止了Java的重排序，trycatch里面的代码不会被编译器优化重排。重排序是编译器在不改变单线程程序语义的前提下，可以重新安排语句的执行顺序。\n" +
                "    简而言之，try会阻止Java对代码进行重排序，也就是放弃了Java对代码的优化。效率肯定比重排序低，所以说，try中的代码越少越好。\n" +
                "    当然，如果你不能很好的把握哪里会爆异常，哪里不会，在保证代码正确运行的前提下，再去尝试性的缩小trycatch的范围吧。\n" +
                "    而代码的重排序最关键的地方就是即时编译器，下面来介绍一下即时编译器，也是本篇的重点。");

        System.out.println();
    }

    /**
     * 测试1
     */
    public static void test01() {
        boolean ret = true;
        try {
            ret = test02();
        } catch (Exception e) {
            System.out.println("test01 error:" + e.getMessage());
            ret = false;
        } finally {
            System.out.println("test01,finally, return -> " + ret);
        }
    }

    public static boolean test02() {
        boolean ret = true;
        try {
            // 问题1：test03发生异常了，虽然try catch了，但调用的地方没有接收
            test03();
            System.out.println("因为test03报错，我不应该执行。");
            return ret;
        } catch (Exception e) {
            System.out.println("test02 error:"+e.getMessage());
            ret = false;
            throw e;
        } finally {
            System.out.println("test02 finally, return -> " + ret);
            return ret;
        }
    }

    public static boolean test03() throws Exception {
        boolean ret = true;
        try {
            System.out.println("即将发生异常");
            int a = 1/0;
            System.out.println(a);
            System.out.println("发生异常后，还有走我吗？");
            return true;
        } catch (Exception e) {
            System.out.println("test03 error: " + e.getMessage() );
            ret = false;
            throw e;
        } finally {
            System.out.println("test03 finally, return -> " + ret);
            return ret;
        }
    }

}
